package pers.dawnyang.modular.system.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import pers.dawnyang.common.core.annotation.SP;
import pers.dawnyang.common.core.domain.entity.SysRole;
import pers.dawnyang.common.core.domain.entity.SysRoleMenu;
import pers.dawnyang.common.core.util.MyTools;
import pers.dawnyang.config.security.SecurityUtil;
import pers.dawnyang.modular.system.domain.request.role.RoleMenuReqU;
import pers.dawnyang.modular.system.domain.request.role.RoleReqR;
import pers.dawnyang.modular.system.domain.request.role.SavePermsReq;
import pers.dawnyang.modular.system.domain.response.role.Perms;
import pers.dawnyang.modular.system.domain.response.role.RoleMenuRes;
import pers.dawnyang.modular.system.domain.response.role.RoleRes;
import pers.dawnyang.modular.system.mapper.SysRoleMapper;
import pers.dawnyang.modular.system.mapper.SysRoleMenuMapper;
import pers.dawnyang.modular.system.service.RoleService;

/**
 * @author dawn
 * @date 2021/02/08
 */
@Service
public class RoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements RoleService {

  @Autowired
  private SysRoleMapper sysRoleMapper;

  @Autowired
  private SysRoleMenuMapper sysRoleMenuMapper;

  @SP
  @Override
  public IPage<RoleRes> getPage(Page<RoleRes> page, RoleReqR req) {
    // SqlTools.montageSql(req);
    return sysRoleMapper.getPage(page, req);
  }

  @Override
  public List<Perms> getPermsList(Long roleId) {
    List<Perms> authPerms = sysRoleMapper.getAuthPerms(roleId);
    List<Perms> allPerms = sysRoleMapper.getAllPerms();
    allPerms.forEach(perms -> {
      if (authPerms.contains(perms)) {
        perms.setCheckArr("1");
      } else {
        perms.setCheckArr("0");
      }
    });
    return allPerms;
  }

  @Override
  public void savePerms(SavePermsReq req) {
    LambdaQueryWrapper<SysRoleMenu> lqw = new LambdaQueryWrapper<>();
    lqw.eq(SysRoleMenu::getRoleId, req.getRoleId());
    sysRoleMenuMapper.delete(lqw);
    String[] menuIds = req.getMenuIds();
    for (String menuId : menuIds) {
      SysRoleMenu sysRoleMenu = new SysRoleMenu();
      sysRoleMenu.setRoleId(req.getRoleId());
      sysRoleMenu.setMenuId(Long.valueOf(menuId));
      sysRoleMenuMapper.insert(sysRoleMenu);
    }
  }

  @Override
  public List<RoleMenuRes> getRoleMenu(Long roleId) {
    List<RoleMenuRes> all = sysRoleMenuMapper.getAllMenu();
    List<RoleMenuRes> match = sysRoleMenuMapper.getRoleMenu(roleId);
    all.forEach(res -> {
      if (match.contains(res)) {
        res.setCheckArr("1");
      } else {
        res.setCheckArr("0");
      }
    });
    return all;
  }

  @Override
  public void saveRoleMenu(RoleMenuReqU req) {
    Long roleId = req.getRoleId();
    String lastIds = req.getLastMenuIds();
    String ids = req.getMenuIds();
    List<String> add = MyTools.getDiff(lastIds, ids);
    if (add != null && add.size() > 0) {
      for (String str : add) {
        SysRoleMenu sysRoleMenu = new SysRoleMenu();
        sysRoleMenu.setRoleId(roleId);
        sysRoleMenu.setMenuId(Long.valueOf(str));
        sysRoleMenuMapper.insert(sysRoleMenu);
      }
    }
    List<String> delete = MyTools.getDiff(ids, lastIds);
    if (delete != null && delete.size() > 0) {
      for (String str : delete) {
        LambdaQueryWrapper<SysRoleMenu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SysRoleMenu::getRoleId, roleId);
        lqw.eq(SysRoleMenu::getMenuId, Long.valueOf(str));
        sysRoleMenuMapper.delete(lqw);
      }
    }

  }

  @Override
  public boolean checkRoleLevel(Long roleId) {
    Long minRoleSort = SecurityUtil.getUserMinRoleLevel();
    SysRole targetRole = sysRoleMapper.selectById(roleId);
    if (targetRole.getRoleSort() <= minRoleSort) {
      return false;
    }
    return true;
  }

}
